﻿using System;
using System.Collections.Generic;
using System.Linq;
using ITTestingSystem.BusinessLogic.DataServices.Abstract;

namespace ITTestingSystem.BusinessLogic.UnitTests.AdditionalClasses
{
    public class MockRepository<T> : IRepositoryForEntity<T> where T : class
    {
        private readonly List<T> _mockEntitiesSet = new List<T>();

        public void Add(T entity)
        {
            if (IsNull(entity))
            {
                throw new ArgumentNullException();
            }

            _mockEntitiesSet.Add(entity);
        }

        public IQueryable<T> GetAll()
        {
            return _mockEntitiesSet.Select(entity => entity).AsQueryable();
        }

        public T GetById(int id)
        {
            T entity;

            try
            {
                entity = _mockEntitiesSet[id];
            }
            catch (ArgumentOutOfRangeException)
            {
                // Real repository returns null if entity isn't finded by id

                entity = null;
            }

            return entity;
        }

        public void Update(T entity)
        {
            if (IsNull(entity))
            {
                throw new ArgumentNullException();
            }

            var id = _mockEntitiesSet.FindIndex(e => e == entity);

            if (id == -1)
            {
                // Real repository doesn't throw exception if entity isn't finded

                return;
            }

            _mockEntitiesSet[id] = entity;
        }

        public void DeleteById(int id)
        {
            try
            {
                _mockEntitiesSet.RemoveAt(id);
            }
            catch (ArgumentOutOfRangeException)
            {
                // Real repository returns call if entity isn't finded
            }
        }

        public void Delete(T entity)
        {
            if (IsNull(entity))
            {
                throw new ArgumentNullException();
            }

            _mockEntitiesSet.Remove(entity);
        }

        public void Save()
        { }

        private static bool IsNull(object parameter)
        {
            return parameter == null;
        }
    }
}
